/**
 * @公用函数
 */

/**
 * @description 校验手机格式
 * @property {String} mobile 手机号
 */
function checkMobile(mobile) {

	return RegExp(
			/^(((13[0-9]{1})|(14[0-9]{1})|(15[0-9]{1})|(16[0-9]{1})|(18[0-9]{1})|(17[0-9]{1})|(19[0-9]{1}))+\d{8})$/)
		.test(mobile);
}

/**
 * @description 校验身份证号
 * @property {String} card 身份证号
 */
function checkIDNumber(card) {
	// 身份证号码为15位或者18位，15位时全为数字，18位前17位为数字，最后一位是校验位，可能为数字或字符X 
	var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
	if (reg.test(card) === false) {
		// alert("身份证输入不合法");
		return false;
	} else {
		return true;
	}
}

/**
 * @description json数据互转
 * @param {Object} obj: json
 * @param {Object} type: 0转字符串、1转json
 */
function jsonParse(obj, type) {
	let json;
	switch (type) {
		case 0:
			json = JSON.stringify(obj)
			break
		case 1:
			json = JSON.parse(obj)
			break
		default:
			break
	}

	return json
}

/**
 * @description json数据互转 单位：秒
 */
function nowTimestamp() {
	let timestamp = new Date().getTime() / 1000;

	return timestamp
}

/**
 * @description 年月日 时分秒转时间戳
 */
function formatTimestamp(str) {
	let time = new Date(str),
		timestamp = time.getTime() / 1000

	return timestamp
}

/**
 * @description 数据转化
 * @param {Object} n：数据转化
 */
function formatNumber(n) {
	n = n.toString()

	return n[1] ? n : '0' + n
}

/**
 * @description 时间戳转化为年 月 日 时 分 秒
 * number: 传入时间戳
 * format：返回格式，支持自定义，但参数必须与formateArr里保持一致
 * 使用方法：formatTime(时间戳, 'Y-M-D h:m:s')
 */
function formatTime(number, format) {
	var formateArr = ['Y', 'M', 'D', 'h', 'm', 's'];
	var returnArr = [];

	var date = new Date(number * 1000);
	returnArr.push(date.getFullYear());
	returnArr.push(formatNumber(date.getMonth() + 1));
	returnArr.push(formatNumber(date.getDate()));
	returnArr.push(formatNumber(date.getHours()));
	returnArr.push(formatNumber(date.getMinutes()));
	returnArr.push(formatNumber(date.getSeconds()));

	for (var i in returnArr) {
		format = format.replace(formateArr[i], returnArr[i]);
	}

	return format;
}

/**
 * @description 计算时间差
 * @param {Object} d1	开始时间
 * @param {Object} d2	结束时间
 * @param {Object} str   返回结果
 * 使用方法： dateDiff("2021-11-1","2021-11-20","相差Y年M月D天");
 */
function dateDiff(d1, d2, str) {
	d1 = new Date(d1.replace(/-/g, '/'));
	d2 = new Date(d2.replace(/-/g, '/'));
	var obj = {},
		M1 = d1.getMonth(),
		D1 = d1.getDate(),
		M2 = d2.getMonth(),
		D2 = d2.getDate();
	obj.Y = d2.getFullYear() - d1.getFullYear() + (M1 * 100 + D1 > M2 * 100 + D2 ? -1 : 0);
	obj.M = obj.Y * 12 + M2 - M1 + (D1 > D2 ? -1 : 0);
	obj.s = Math.floor((d2 - d1) / 1000); //差几秒
	obj.m = Math.floor(obj.s / 60); //差几分钟
	obj.h = Math.floor(obj.m / 60); //差几小时
	obj.D = Math.floor(obj.h / 24); //差几天  
	return str.replace(/\w/g, function(a) {
		return obj[a] ? obj[a] : a !== 'Y' && a !== 'M' && a !== 'D' ? a : 0
	});
}

/**
 * @description 根据时间戳计算当前时间距离开始时间差
 */
function dataDis(val) {
	let startTime = nowTimestamp() * 1000,
		h, m, s;
	let date = (val * 1000) - startTime; // 结束时间
	// 计算出小时数
	var dayMS = date % (24 * 3600 * 1000 * 60); // 计算天数后剩余的毫秒数
	var hours = Math.floor(dayMS / (3600 * 1000));
	h = hours > 0 ? hours : 0
	// 计算相差分钟数
	var hoursMS = dayMS % (3600 * 1000); // 计算小时数后剩余的毫秒数
	var minutes = Math.floor(hoursMS / (60 * 1000));
	m = minutes > 0 ? minutes : 0;
	// 计算相差秒数
	var minutesMS = hoursMS % (60 * 1000); // 计算分钟数后剩余的毫秒数
	var second = minutesMS / 1000;
	s = second > 0 ? second : 0;

	return h + ':' + m + ':' + s
}

/**
 * @description 获取随机数
 * @property {Number} number  随机位数  默认8位随机数 
 */
function randNum(number) {
	let rand = '';
	for (var i = 0; i < Number(number) || 8; i++) {
		rand += Math.floor(Math.random() * 10);
	}

	return rand
}


/**
 * @param {Object} str: 用户名加密*号代替
 */
function formatName(str) {
	// return new Array(str.length).join('*') + str.substr(-1);		// 显示最后一字其他替换成星号
	return str.substring(0, 1) + new Array(str.length).join('*') // 显示第一个字其他替换成星号
}

/**
 * @description 数组根据时间倒序/正序
 * @param {array} arr 倒序  反之a.time.localeCompare(b.time)正序
 * @param {String} mode  reverse 倒序   positive 正序 
 */
function formatYearsSort(arr, mode = 'reverse') {
	if(mode == 'reverse') {
		return arr.sort((a, b) => b.time.localeCompare(a.time))
	} else {
		return arr.sort((a, b) => a.time.localeCompare(b.time))
	}
}

/**
 * @description 返回上一页
 * @property {String} url  如果没有上一页时跳转路径  默认/pages/index/index  默认条跳转类型 switchTab  可选值 ['navigateTo', 'switchTab', 'reLaunch', 'redirectTo']
 */
function overBack(url, type = 'switchTab') {
	let pages = getCurrentPages();
	let currPage = pages[pages.length - 1]; // 当前页面
	let prevPage = pages[pages.length - 2]; // 上一页面
	if (prevPage) {
		uni.navigateBack()
	} else {
		if (!['navigateTo', 'switchTab', 'reLaunch', 'redirectTo'].includes(type)) {
			throw new Error(`name:${name}里面的type必须是以下的值['navigateTo', 'switchTab', 'reLaunch', 'redirectTo']`)
		}
		uni[type]({
			url: url || '/pages/index/index'
		})
	}
}

/**
 * @description 拨打电话
 * @param {Object} value：电话号
 */
function dialingPhone(value) { // 拨打电话函数处理事件
	uni.makePhoneCall({
		phoneNumber: value,
		success: res => {
			console.log('回调成功')
		},
		fail: err => {
			uni.showToast({
				title: err,
				icon: 'none'
			})
		}
	})
}

/**
 * @description 一键复制
 * @param {Object} str  
 */
function copy(str) {
	uni.setClipboardData({
		data: str, // 要复制的内容
		success: res => { // 复制成功回调函数
			uni.showToast({
				title: '复制成功'
			})
		}
	})
}

/**
 * @description 一键粘贴
 */
function stickup() {
	return new Promise((resolve, reject) => {
		uni.getClipboardData({
			success: res => {
				resolve(res.data)
			},
			fail: err => {
				reject(err)
			}
		})
	})
}

/**
 * @description 防止快速连续点击,节流函数
 */
function throttle(fun, delay) {
	let oadDate = Date.now();
	return function() {
		let _this = this;
		let args = arguments;
		let newDate = Date.now();
		if (newDate - oadDate > delay) {
			fun.apply(_this, args);
			oadDate = Date.now();
		} else {
			uni.showToast({
				title: '请不要频繁点击哦~',
				icon: 'none'
			})
		}
	}
}

/**
 * @description 根据某字段查找在当前数组所在索引
 * @property {array} arr  数组
 * @property {String} dst  匹配value
 * @property {String} str  匹配key  不传默认id 
 */
function arrayIndex(arr, dst, str) {
	let i = arr.length;
	while ((i -= 1) > -1) {
		if (arr[i][str || 'id'] === dst) {
			return i
		}
	}
	return false
}

/**
 * @description sku组合算法
 */
function cartesianProductOf() {
	return Array.prototype.reduce.call(arguments, function(a, b) {
		var ret = [];
		a.forEach(function(a) {
			b.forEach(function(b) {
				ret.push(a.concat([b]));
			})
		})
		return ret
	}, [
		[]
	]);
}

/**
 * @description 点击跳转其他小程序
 */
function jumpApplet(params) {
	uni.navigateToMiniProgram({
		appId: params,
		envVersion: 'develop', // develop（开发版），trial（体验版），release（正式版）
		success: res => {
			console.log('打开成功')
		},
		fail: err => {
			console.log('打开失败')
		}
	})
}

/**
 * @description 数字转换中文
 */
function formatSection(num) {
	let numChar = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
	let arr = (num + '').split('').reverse();
	let str = ''
	for (let i = 0; i < arr.length; i++) { //将0-9转化为零到九
		let char = arr[i] == 0 ? numChar[0] : numChar[arr[i]] //当数字为0时不加权位，非零加权位 
		str = char + str;
	}

	return str
}

/**
 * @description 判断是否存在空
 * @param {Array} arr  数组
 */
function isNull(arr) {
	let status = arr.find((res) => {
		if (!res.value) {
			return res
		}
	})

	return !status ? true : false
}

/**
 * @description json数据互转
 * @param {Object} params: json
 * @param {Object} type: 0转字符串、1转json
 */
function jsonParse(params, type) {
	let json;
	switch (type) {
		case 0:
			json = JSON.stringify(params)
			break
		case 1:
			json = JSON.parse(params)
			break
		default:
			break
	}

	return json
}

/**
 * @description 浏览历史
 * @param {Array} arr 数组
 * @param {Object} data 对象
 */
function footmarkList(arr, data) {
	if (arr.length < 10) { // 当数组长度小于10时，直接插入数据
		if (!isDuplicate(arr, data)) { // 如果数据不重复，则插入
			arr.push(data)
		}
	} else { // 当数组长度大于等于10时，删除最早数据，再插入新数据
		if (!isDuplicate(arr, data)) { // 如果数据不重复，则插入
			arr.shift(); // 删除最早数据
			arr.push(data) // 插入新数据
		}
	}
	return arr
}

function isDuplicate(arr, data) {
	for (let i = 0; i < arr.length; i++) {
		if (arr[i]._id === data._id) {
			return true;
		}
	}
	return false;
}

/**
 * 判断路径是本地还是网络
 */
function isRemoteImage(url) {
	let state = false;
	if (url.startsWith("http://tmp")) {
		state = false;
	} else if (url.startsWith("https://") || url.startsWith("http://")) {
		state = true;
	}
	return state;
}

/**
 * @description base64转换
 */
function base64Save(base64File) {
	// #ifdef MP-WEIXIN
	const fsm = wx.getFileSystemManager();
	let extName = base64File.match(/data\:\S+\/(\S+);/);
	if (extName) {
		extName = extName[1];
	}
	let fileName = Date.now() + '.' + extName;
	return new Promise((resolve, reject) => {
		let filePath = wx.env.USER_DATA_PATH + '/' + fileName;
		fsm.writeFile({
			filePath,
			data: base64File.replace(/^data:\S+\/\S+;base64,/, ''),
			encoding: 'base64',
			success: (res) => {
				resolve(filePath);
			},
		});
	});
	// #endif
}

/**
 * @description  rpx转px
 * @param {Object} rpx  值
 */
function rpxToPx(rpx) {
	return uni.upx2px(rpx)
}


/**
 * @description  px转rpx
 * @param {Object} px 值
 */
function pxToRpx(px) {
	return px / (uni.upx2px(100) / 100);
}

/**
 * @description 显示消息提示框
 * @param {String} title 提示的内容，长度与 icon 取值有关。
 * @param {Number} duration 提示的延迟时间，单位毫秒，默认：1000
 */
function toast(title, duration = 1000) {
	uni.showToast({
		title: String(title),
		icon: 'none',
		duration,
		mask: true
	})
}

const $uy = {
	checkMobile, // 校验手机格式
	checkIDNumber, // 校验身份证号
	jsonParse, // json数据互转
	nowTimestamp, // 获取当前时间戳
	formatTimestamp, // 年月日 时分秒转时间戳
	formatTime, // 时间戳转化为年 月 日 时 分 秒
	dateDiff, // 计算时间戳相差
	dataDis, // 根据时间戳计算当前时间距离开始时间差
	randNum, // 随机获取8位数
	formatName, // 用户名加密*号代替
	overBack, // 返回上一页
	dialingPhone, // 拨打电话
	copy, // 一键复制
	stickup, // 一键粘贴
	throttle, // 防止快速连续点击,节流函数
	arrayIndex, // 根据某字段查找在当前数组所在索引
	cartesianProductOf, // sku组合算法
	jumpApplet, // 点击跳转其他小程序
	formatSection, // 数字转换中文,
	isNull, // 判断是否存在空
	jsonParse, // json数据互转
	footmarkList, // 浏览历史
	isRemoteImage, // 判断路径是本地还是网络
	base64Save, // base64转换
	rpxToPx, // rpx转px
	pxToRpx, // px转rpx
	toast, // 显示消息提示框
}

uni.$uy = $uy

module.exports = $uy